package com.ebt.m.customer.view;

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.ebt.m.AppContext;
import com.ebt.m.AppInitService;
import com.ebt.m.R;
import com.ebt.m.commons.buscomponent.listview.pulltorefresh.PullToRefreshView;
import com.ebt.m.commons.buscomponent.permission.RxPermissions;
import com.ebt.m.commons.utils.NetUtils;
import com.ebt.m.commons.utils.RxUtil;
import com.ebt.m.commons.widgets.BaseRxFragment;
import com.ebt.m.customer.CustomerUtil;
import com.ebt.m.customer.constant.CustomerConstant;
import com.ebt.m.customer.db.CustomerDBManager;
import com.ebt.m.customer.entity.CustomerSimple;
import com.ebt.m.customer.event.EventCustomerListRefreshOnly;
import com.ebt.m.customer.event.EventCustomerMainContentViewDetach;
import com.ebt.m.customer.event.EventCustomerRefresh;
import com.ebt.m.customer.event.EventRefreshBadge;
import com.ebt.m.customer.model.CustomerModelNew;
import com.ebt.m.customer.net.json.CustomerListJson;
import com.ebt.m.customer.ui.ActivityCustomerImport;
import com.ebt.m.customer.util.CustomerConvertUtil;
import com.ebt.m.customer.util.CustomerNavigator;
import com.ebt.m.customer.util.MultiChooseManager;
import com.ebt.m.data.entity.Customer;
import com.ebt.m.data.rxModel.api.EBTAPI;
import com.ebt.m.event.LoginEvent;
import com.ebt.m.homepage.MessageEvent;
import com.ebt.m.utils.TalkingDataUtil;
import com.ebt.m.widget.EBTProgress;
import com.jakewharton.rxbinding2.view.RxView;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;

/**
 * 流程：
 * 只通过网络获取所有客户，并进行显示
 * 不进行本地存储
 */
public class CustomerMainContentView extends FrameLayout {

    private View mEmptyView;
    private ImageView mEmptyImageView;
    private TextView mEmptyTextView;

    //view
    private View mContentView;
    private View mCustomerNewView;
    private View mCustomerImportView;
    private RecyclerView mRecyclerView;
    private LinearLayoutManager mLinearLayoutManager;
    private IViewFactory mFactory;
    private AdapterForRecyclerView mAdapter;
    private PullToRefreshView mSwipeRefreshLayout;
    private BadgeView mBadgeView;

    //data
    public static final int PRE_EXTRA_SIZE = 1;
    private ArrayList<CustomerModelNew> mCustomerModelNews = new ArrayList();
    private HashMap<Integer, Integer> mSectionToPosition = new HashMap();
    private int mModelSize;

    //scroll相关数据
    private int mTargetPosition = -1;
    private boolean mFlagMove = false;

    private EBTProgress progress;
    private RxPermissions rxPermissions;

    //数据接收时的回调
    public interface UpdateListener {
        void onUpdateFinish(List<CustomerModelNew> customerModelNews);

        void onUpdateStart();

        void onUpdateError();
    }

    public CustomerMainContentView(Context context) {
        super(context);
    }

    public CustomerMainContentView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mContentView = inflate(context, R.layout.view_customer_main_content, this);
        init();
    }

    private void init() {
        findViews();
        initSwipeLayout();
        setRecyclerViewTarget();
        initViewFactory();
        initRecyclerView();
        setupListeners();
    }

    private void findViews() {
        progress = (EBTProgress) mContentView.findViewById(R.id.progress);
        mEmptyView = mContentView.findViewById(R.id.empty_view);
        mEmptyImageView = (ImageView) mContentView.findViewById(R.id.iv_empty);
        mEmptyTextView = (TextView) mContentView.findViewById(R.id.tv_empty);

        mRecyclerView = (RecyclerView) mContentView.findViewById(R.id.rv);
        mCustomerNewView = mContentView.findViewById(R.id.customer_new);
        mCustomerImportView = mContentView.findViewById(R.id.customer_import);
        mSwipeRefreshLayout = (PullToRefreshView) mContentView.findViewById(R.id.swipe_layout);
        mBadgeView = (BadgeView) mContentView.findViewById(R.id.badge_view);
    }

    private void initSwipeLayout() {
        mSwipeRefreshLayout.setOnRefreshListener(new PullToRefreshView.OnRefreshListener() {
            @Override
            public void onRefresh() {
                mShowToast = true;
                refresh();
            }
        });
    }

    private void initViewFactory() {
        if (mFactory == null) {
            mFactory = new IViewFactory() {
                @Override
                public ICustomizedViewNew createView(int type) {   //type就是position
                    if (type == 0) {
                        CustomerItemMainActiveView view = new CustomerItemMainActiveView(getContext(), CustomerUtil.FROM_OTHER);
                        return view;
                    } else if (type > 0) {
                        return new CustomerItemMainNormal(getContext());
                    }
                    return null;
                }
            };
        }
    }

    private void initRecyclerView() {
        if (mLinearLayoutManager == null) {
            mLinearLayoutManager = new LinearLayoutManager(this.getContext());
        }
        mRecyclerView.setLayoutManager(mLinearLayoutManager);
        mRecyclerView.clearOnScrollListeners();
        mRecyclerView.addOnScrollListener(new ScrollListener());

        mCustomerModelNews.clear();
        mModelSize = mCustomerModelNews.size();
        mSectionToPosition.clear();
        if (mAdapter == null) {
            mAdapter = new AdapterForRecyclerView(mCustomerModelNews);
            mRecyclerView.setAdapter(mAdapter);
        }
    }

    private void setupListeners() {

        RxView.clicks(mCustomerNewView)
                .throttleFirst(500, TimeUnit.MILLISECONDS)
                .subscribe(aVoid -> {
                    addCustomer();
                    TalkingDataUtil.onEvent(TalkingDataUtil.TYPE_CUSTOMER_ADD);
                });
        RxView.clicks(mCustomerImportView)
                .throttleFirst(500, TimeUnit.MILLISECONDS)
                .subscribe(aVoid -> {
                    importCustomer();
                    TalkingDataUtil.onEvent(TalkingDataUtil.TYPE_CUSTOMER_IMPORT);
                });
    }

    private boolean mShowToast;

    private void refresh() {
        if (!AppContext.getCurrentUser().isLogined()) {
            showToast("请先登录");
            hideRefreshing();
            hideProgress();
            return;
        }

        if (mUpdateListener != null) {
            mUpdateListener.onUpdateStart();
        }
        if (!NetUtils.isNetworkAvailable(getContext().getApplicationContext())) {
            getLocalCustomers();
        } else {
            getNetCustomers();
        }
        setBadgeViewText();
    }

    private void getLocalCustomers() {
        Observable
                .create(
                        new ObservableOnSubscribe<List<CustomerSimple>>() {
                            @Override
                            public void subscribe(ObservableEmitter<List<CustomerSimple>> emitter) throws Exception {
                                List<CustomerSimple> list = CustomerDBManager
                                        .getInstance()
                                        .getSimpleCustomers(getContext());
                                emitter.onNext(list);
                                emitter.onComplete();
                            }
                        })
                .observeOn(AndroidSchedulers.mainThread())
                .subscribeOn(Schedulers.io())
                .subscribe(new Observer<List<CustomerSimple>>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onComplete() {
                        hideProgress();
                    }

                    @Override
                    public void onError(Throwable e) {
                        e.printStackTrace();
                        hideProgress();
                    }

                    @Override
                    public void onNext(List<CustomerSimple> list) {
                        showCustomerSimpleList(list);
                        if (list == null || list.size() == 0) {
                            updateEmptyViewsForNet(mRecyclerView);
                        }
                        hideRefreshing();
                        hideProgress();
                    }
                });
    }

    private void setBadgeViewText() {
        if (rxPermissions == null) {
            rxPermissions = new RxPermissions((Activity) getContext());
        }
        rxPermissions.request(Manifest.permission.READ_CONTACTS)
                .subscribe(permission -> {
                    if (permission) {
                        Observable.create(
                                new ObservableOnSubscribe<String>() {
                                    @Override
                                    public void subscribe(ObservableEmitter<String> e) throws Exception {
                                        long number = CustomerDBManager.getInstance().getBadgeViewNum(getContext());
                                        String numberS = "";
                                        if (number > 99) {
                                            numberS = "99+";
                                        } else if (number > 0) {
                                            numberS = String.valueOf(number);
                                        } else {
                                            numberS = "";
                                        }
                                        e.onNext(numberS);
                                        e.onComplete();
                                    }
                                })
                                .observeOn(AndroidSchedulers.mainThread())
                                .subscribeOn(Schedulers.io())
                                .subscribe(new Observer<String>() {
                                    @Override
                                    public void onSubscribe(Disposable d) {

                                    }

                                    @Override
                                    public void onComplete() {
                                    }

                                    @Override
                                    public void onError(Throwable e) {
                                        e.printStackTrace();
                                    }

                                    @Override
                                    public void onNext(String number) {
                                        if (TextUtils.isEmpty(number)) {
                                            mBadgeView.setVisibility(View.INVISIBLE);
                                        } else {
                                            mBadgeView.setText(number);
                                            mBadgeView.setVisibility(View.VISIBLE);
                                        }
                                    }
                                });
                    } else {
                    }
                });
    }

    private void getNetCustomers() {
        EBTAPI ebtapi = AppInitService.getEbtApi();
        ebtapi.getCustomerList().compose(RxUtil.rxTransformer(baseRxFragment)).subscribe(getCustomerListSubscriber());
    }

    private void showToast(String message) {
        if (mShowToast) {
            Toast.makeText(getContext().getApplicationContext(), message, Toast.LENGTH_SHORT).show();
        }
    }

    private Observer<CustomerListJson> getCustomerListSubscriber() {
        return new Observer<CustomerListJson>() {
            @Override
            public void onComplete() {
                hideRefreshing();
                hideProgress();
            }

            @Override
            public void onSubscribe(Disposable d) {

            }

            @Override
            public void onError(Throwable e) {
                e.printStackTrace();
                showToast("无法获取客户列表 ");
                hideRefreshing();
                hideProgress();
                onUpdateError();
            }

            @Override
            public void onNext(CustomerListJson customerListJson) {
                if (customerListJson == null) {
                    showToast("获取的客户列表为空");
                    hideRefreshing();
                    hideProgress();
                    onUpdateError();
                    return;
                }
                if (customerListJson.error != null) {
                    showToast("获取的客户列表出错 \n" + "出错代码为:" + customerListJson.error.message);
                    hideRefreshing();
                    hideProgress();
                    onUpdateError();
                    return;
                }
                if (customerListJson.error == null) {
                    if (customerListJson.data == null) {
                        showToast("获取的客户列表为空");
                        hideRefreshing();
                        hideProgress();
                        onUpdateError();
                        return;
                    } else {
                        showCustomerList(customerListJson);
                        storeCustomerList(customerListJson);
                        if (customerListJson.data.size() == 0) {
                            updateEmptyViewsForData(mRecyclerView, false);
                        } else {
                            updateEmptyViewsForData(mRecyclerView, true);
                        }
                        hideRefreshing();
                        hideProgress();
                    }
                }
            }
        };
    }

    private void onUpdateError() {
        if (mUpdateListener != null) {
            mUpdateListener.onUpdateError();
        }
    }

    private void hideRefreshing() {
        if (mSwipeRefreshLayout != null) {
            mSwipeRefreshLayout.setRefreshing(false);
        }
    }

    private void showRefreshing() {
        if (mSwipeRefreshLayout != null) {
            mSwipeRefreshLayout.setRefreshing(true);
        }
    }

    private void storeCustomerList(CustomerListJson customerListJson) {

        if (customerListJson == null) {
            return;
        }
        Thread insertCustomer = new Thread() {
            @Override
            public void run() {
                CustomerDBManager
                        .getInstance()
                        .clearTable(getContext().getApplicationContext(), CustomerConstant.CustomerSimple.TABLE_NAME);
                CustomerDBManager
                        .getInstance()
                        .saveSimpleCustomers(getContext().getApplicationContext(), customerListJson.data);
            }
        };
        insertCustomer.start();
    }

    private void showCustomerSimpleList(List<CustomerSimple> customerSimples) {
        List<CustomerModelNew> list = new ArrayList<>();
        if (customerSimples != null) {
            list = CustomerConvertUtil.convertCustomerListToCustomerModelNewList(customerSimples);
        }

        mCustomerModelNews.clear();
        mCustomerModelNews.addAll(list);

        //将所有的uuid设置到MultiChooseManager中
        List<String> uuids = new ArrayList<>();
        for (CustomerModelNew item : mCustomerModelNews) {
            uuids.add(item.getCustomerUuid());
        }
        MultiChooseManager.getInstance().setAllUuids(uuids);

        mModelSize = mCustomerModelNews.size();
        mSectionToPosition.clear();
        if (mAdapter == null) {
            mAdapter = new AdapterForRecyclerView(mCustomerModelNews);
            mRecyclerView.setAdapter(mAdapter);
        } else {
            mAdapter.notifyDataSetChanged();
        }
        if (mUpdateListener != null) {
            mUpdateListener.onUpdateFinish(mCustomerModelNews);
        }

    }

    private void showCustomerList(CustomerListJson customerListJson) {
        if (customerListJson != null) {
            showCustomerSimpleList(customerListJson.data);
        }
    }

    private UpdateListener mUpdateListener;

    //fragment调用
    public void update(UpdateListener updateListener) {
        mUpdateListener = updateListener;
        showProgress();
//        showRefreshing();
        refresh();
    }

    private void showProgress() {
        if (progress != null) {
            progress.setVisibility(View.VISIBLE);
        }
    }

    private void hideProgress() {
        if (progress != null) {
            progress.setVisibility(View.GONE);
        }
    }


    public void setSelection(int position) {
        moveToPosition(position);
    }

    private void moveToPosition(int position) {
        mTargetPosition = position;
        int firstItem = mLinearLayoutManager.findFirstVisibleItemPosition();
        int lastItem = mLinearLayoutManager.findLastVisibleItemPosition();
        if (position <= firstItem) {
            mRecyclerView.scrollToPosition(position);
        } else if (position <= lastItem) {
            int top = mRecyclerView.getChildAt(position - firstItem).getTop();
            mRecyclerView.scrollBy(0, top);
        } else {
            mRecyclerView.scrollToPosition(position);
            mFlagMove = true;
        }
    }


    public interface IViewFactory {
        ICustomizedViewNew createView(int type);
    }

    class ScrollListener extends RecyclerView.OnScrollListener {
        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);
            if (mFlagMove) {
                mFlagMove = false;
                int n = mTargetPosition - mLinearLayoutManager.findFirstVisibleItemPosition();
                if (0 <= n && n < mRecyclerView.getChildCount()) {
                    int top = mRecyclerView.getChildAt(n).getTop();
                    mRecyclerView.scrollBy(0, top);
                }
            }
        }
    }

    class AdapterForRecyclerView extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

        private List<CustomerModelNew> customerModelMultis;

        public AdapterForRecyclerView(List<CustomerModelNew> customerModelMultis) {
            this.customerModelMultis = customerModelMultis;
        }

        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            return new CustomerMainViewHolder(mFactory.createView(viewType).getView());
        }

        @Override
        public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
            ICustomizedViewNew iCustomizedView = (ICustomizedViewNew) holder.itemView;
            if (position < PRE_EXTRA_SIZE) {
            } else {
                iCustomizedView.update(customerModelMultis.get(position - PRE_EXTRA_SIZE));
                int section = getSectionForPosition(position - PRE_EXTRA_SIZE);
                int firstPosition = getPositionForSection(section);
                if (firstPosition + PRE_EXTRA_SIZE == position) {
                    if (section < 0) {
                        section = 0;
                    } else if (section >= CustomerConstant.Sort.CHARS_ALPHA_SIZE) {
                        section = CustomerConstant.Sort.CHARS_ALPHA_SIZE - 1;
                    }
                    iCustomizedView.showSortTitle(String.valueOf(CustomerConstant.Sort.CHARS_ALPHA[section]));
                } else {
                    iCustomizedView.showSortTitle(null);
                    //隐藏title
                }
            }
        }

        @Override
        public int getItemCount() {
            return customerModelMultis.size() + PRE_EXTRA_SIZE;
        }

        @Override
        public int getItemViewType(int position) {
            if (position < PRE_EXTRA_SIZE) {
                return 0;
            }
            return 1;
        }

        class CustomerMainViewHolder extends RecyclerView.ViewHolder {
            public CustomerMainViewHolder(View itemView) {
                super(itemView);
            }
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEventMainThread(LoginEvent event) {
        mShowToast = false;
        showRefreshing();
        refresh();
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEventMainThread(Customer event) {
        mShowToast = false;
        update(mUpdateListener);
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEventMainThread(EventCustomerRefresh event) {
        mShowToast = false;
        update(mUpdateListener);
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEventMainThread(EventCustomerListRefreshOnly event) {
        mShowToast = false;
        update(mUpdateListener);
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEventMainThread(MessageEvent event) {
        mShowToast = false;
        update(mUpdateListener);
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEventMainThread(EventRefreshBadge event) {
        if (mBadgeView != null) {
            setBadgeViewText();
        }
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        EventBus.getDefault().register(this);
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        EventBus.getDefault().post(new EventCustomerMainContentViewDetach());
        EventBus.getDefault().unregister(this);
    }

    private void importCustomer() {
        Intent intent = new Intent(getContext(), ActivityCustomerImport.class);
        getContext().startActivity(intent);
        ((Activity) getContext()).overridePendingTransition(R.anim.slide_right_in, R.anim.slide_left_out);
    }

    private void addCustomer() {
        CustomerNavigator.startActivityCustomerDetail(getContext());
        ((Activity) getContext()).overridePendingTransition(R.anim.slide_right_in, R.anim.slide_left_out);
    }

    public int getPositionForSection(int section) {

        if (section >= 27) {
            return CustomerConstant.Sort.CHARS_ALPHA_SIZE - 1;
        }
        if (section < 0) {
            return 0;
        }

        Integer p = mSectionToPosition.get(section);
        if (p != null) {
            return p;
        }

        char c = CustomerConstant.Sort.CHARS_ALPHA[section];
        int size = mModelSize;

        for (int i = 0; i < size; i++) {
            if (mCustomerModelNews.get(i).sortKeyChar.charAt(0) >= c) {
                mSectionToPosition.put(section, i);
                return i;
            }
        }
        return -1;
    }

    public int getSectionForPosition(int position) {
        if (position >= mModelSize) {
            return -1;
        }

        char c = mCustomerModelNews.get(position).sortKeyChar.charAt(0);//IndexOutOfBoundsException
        for (int i = 0; i < CustomerConstant.Sort.CHARS_ALPHA_SIZE; i++) {
            if (c == CustomerConstant.Sort.CHARS_ALPHA[i]) {
                return i;
            }
        }
        return -1;
    }

    private boolean updateEmptyViewsForNet(View mainView) {
        if (!NetUtils.isNetworkAvailable(getContext())) {
//            mainView.setVisibility(View.INVISIBLE);
            mEmptyTextView.setText(R.string.customer_no_network);
            mEmptyImageView.setImageResource(R.drawable.ic_no_network);
            mEmptyView.setVisibility(View.VISIBLE);
            return false;
        }
        return true;
    }

    private void updateEmptyViewsForData(View mainView, boolean showMainView) {
        if (showMainView) {
            mEmptyView.setVisibility(View.GONE);
//            mainView.setVisibility(View.VISIBLE);
        } else {
//            mainView.setVisibility(View.GONE);
            mEmptyTextView.setText("没有客户哦");
            mEmptyImageView.setImageResource(R.drawable.ic_no_customer);
            mEmptyView.setVisibility(View.VISIBLE);
        }
    }

    protected void setRecyclerViewTarget() {
        if (mRecyclerView == null) {
            return;
        }
        mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
            }

            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                if (recyclerView.canScrollVertically(-1)) {
                    mSwipeRefreshLayout.setEnabled(false);
                } else {
                    mSwipeRefreshLayout.setEnabled(true);
                }
            }
        });
    }

    public void setBaseRxFragment(BaseRxFragment baseRxFragment) {
        this.baseRxFragment = baseRxFragment;
    }

    private BaseRxFragment baseRxFragment;

}